import json
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.core.exceptions import ValidationError
from django.db import transaction
from django.contrib.auth.decorators import login_required

from rbac.models import Menu, Role, RbacUser
from rbac.auto_permissions import auto_permission_generator

# 添加权限装饰器
require_permission = auto_permission_generator.require_permission


@login_required
@require_permission('rbac.menu_list', '菜单列表', 'RBAC菜单管理', '查看菜单列表的权限')
def menu_list(request):
    """菜单列表页面"""
    menus = Menu.objects.all().order_by('sort_order', 'name')
    roles = Role.objects.filter(is_active=True).order_by('name')
    
    context = {
        'menus': menus,
        'roles': roles,
        'current_user': request.current_user
    }
    return render(request, 'rbac/menu_management.html', context)


@csrf_exempt
@require_http_methods(["POST"])
@require_permission('rbac.menu_add', '添加菜单', 'RBAC菜单管理', '添加新菜单的权限')
def menu_add(request):
    """添加菜单"""
    try:
        data = json.loads(request.body)
        name = data.get('name', '').strip()
        code = data.get('code', '').strip()
        description = data.get('description', '').strip()
        icon = data.get('icon', 'fas fa-cube').strip()
        url = data.get('url', '').strip()
        color = data.get('color', 'primary').strip()
        
        # 安全处理 sort_order 字段
        try:
            sort_order_value = data.get('sort_order', 0)
            if sort_order_value == '' or sort_order_value is None:
                sort_order = 0
            else:
                sort_order = int(sort_order_value)
        except (ValueError, TypeError):
            sort_order = 0
            
        role_ids = data.get('role_ids', [])
        
        if not name or not code or not url:
            return JsonResponse({'success': False, 'message': '菜单名称、代码和链接不能为空'})
        
        # 检查重复
        if Menu.objects.filter(name=name).exists():
            return JsonResponse({'success': False, 'message': '菜单名称已存在'})
        if Menu.objects.filter(code=code).exists():
            return JsonResponse({'success': False, 'message': '菜单代码已存在'})
        
        with transaction.atomic():
            menu = Menu.objects.create(
                name=name,
                code=code,
                description=description,
                icon=icon,
                url=url,
                color=color,
                sort_order=sort_order
            )
            
            # 设置角色权限
            if role_ids:
                roles = Role.objects.filter(id__in=role_ids, is_active=True)
                menu.required_roles.set(roles)
        
        return JsonResponse({
            'success': True, 
            'message': '菜单创建成功',
            'menu': {
                'id': menu.id,
                'name': menu.name,
                'code': menu.code,
                'description': menu.description
            }
        })
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'创建失败: {str(e)}'})


@csrf_exempt
@require_http_methods(["POST"])
@require_permission('rbac.menu_edit', '编辑菜单', 'RBAC菜单管理', '编辑菜单的权限')
def menu_edit(request, menu_id):
    """编辑菜单"""
    try:
        menu = get_object_or_404(Menu, id=menu_id)
        
        data = json.loads(request.body)
        name = data.get('name', '').strip()
        code = data.get('code', '').strip()
        description = data.get('description', '').strip()
        icon = data.get('icon', 'fas fa-cube').strip()
        url = data.get('url', '').strip()
        color = data.get('color', 'primary').strip()
        
        # 安全处理 sort_order 字段
        try:
            sort_order_value = data.get('sort_order', 0)
            if sort_order_value == '' or sort_order_value is None:
                sort_order = 0
            else:
                sort_order = int(sort_order_value)
        except (ValueError, TypeError):
            sort_order = 0
            
        role_ids = data.get('role_ids', [])
        
        if not name or not code or not url:
            return JsonResponse({'success': False, 'message': '菜单名称、代码和链接不能为空'})
        
        # 检查重复（排除当前菜单）
        if Menu.objects.filter(name=name).exclude(id=menu_id).exists():
            return JsonResponse({'success': False, 'message': '菜单名称已存在'})
        if Menu.objects.filter(code=code).exclude(id=menu_id).exists():
            return JsonResponse({'success': False, 'message': '菜单代码已存在'})
        
        with transaction.atomic():
            menu.name = name
            menu.code = code
            menu.description = description
            menu.icon = icon
            menu.url = url
            menu.color = color
            menu.sort_order = sort_order
            menu.save()
            
            # 更新角色权限
            if role_ids:
                roles = Role.objects.filter(id__in=role_ids, is_active=True)
                menu.required_roles.set(roles)
            else:
                menu.required_roles.clear()
        
        return JsonResponse({'success': True, 'message': '菜单更新成功'})
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'更新失败: {str(e)}'})


@csrf_exempt
@require_http_methods(["POST"])
@require_permission('rbac.menu_delete', '删除菜单', 'RBAC菜单管理', '删除菜单的权限')
def menu_delete(request, menu_id):
    """删除菜单"""
    try:
        menu = get_object_or_404(Menu, id=menu_id)
        menu_name = menu.name
        menu.delete()
        
        return JsonResponse({'success': True, 'message': f'菜单"{menu_name}"已删除'})
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'删除失败: {str(e)}'})


@csrf_exempt
@require_http_methods(["POST"])
@require_permission('rbac.menu_toggle', '切换菜单状态', 'RBAC菜单管理', '启用/禁用菜单的权限')
def menu_toggle_status(request, menu_id):
    """切换菜单状态"""
    try:
        menu = get_object_or_404(Menu, id=menu_id)
        menu.is_active = not menu.is_active
        menu.save()
        
        status_text = '启用' if menu.is_active else '禁用'
        return JsonResponse({'success': True, 'message': f'菜单已{status_text}'})
        
    except Exception as e:
        return JsonResponse({'success': False, 'message': f'操作失败: {str(e)}'})


@login_required
def get_menu_roles(request, menu_id):
    """获取菜单的角色列表"""
    try:
        menu = get_object_or_404(Menu, id=menu_id)
        role_ids = list(menu.required_roles.values_list('id', flat=True))
        return JsonResponse({'success': True, 'role_ids': role_ids})
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


@login_required
def welcome(request):
    """欢迎页面 - 显示用户可以访问的菜单"""
    user = request.current_user
    if not user:
        return redirect('rbac:login')
    
    try:
        rbac_user = RbacUser.objects.get(id=user['id'])
        # 获取用户可以访问的菜单
        all_menus = Menu.objects.filter(is_active=True).order_by('sort_order', 'name')
        accessible_menus = []
        
        for menu in all_menus:
            if menu.can_access(rbac_user):
                accessible_menus.append(menu)
        
        context = {
            'current_user': user,
            'menus': accessible_menus,
            'total_menus': len(accessible_menus)
        }
        return render(request, 'rbac/welcome.html', context)
        
    except RbacUser.DoesNotExist:
        messages.error(request, '用户信息异常，请重新登录')
        return redirect('rbac:login')